﻿#pragma once

//实现vtk渲染窗口的功能
#include <vector>

#include <QVTKOpenGLNativeWidget.h>
#include <QOpenGLWidget.h>
#include <vtkGPUVolumeRayCastMapper.h>


#include "vtkSmartPointer.h"
#include "vtkWeakPointer.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkProperty.h"
#include "vtkCamera.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkInteractorStyleJoystickCamera.h"
#include "vtkInteractorStyleSwitch.h"
#include "vtkInteractorStyleRubberBand2D.h"
#include "vtkInteractorStyleDrawPolygon.h"
#include "vtkInteractorStyleRubberBand3D.h"
#include "vtkInteractorStyleRubberBandZoom.h"
#include "vtkInteractorStyleMultiTouchCamera.h"
#include "vtkInteractorStyleUser.h"
#include "vtkInteractorStyleJoystickActor.h"
#include "vtkInteractorStyleFlight.h"
#include "vtkInteractorStyleTerrain.h"
#include "vtkAxesActor.h"
#include "vtkOrientationMarkerWidget.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "vtkMultiVolume.h"



class MyVtkOrientationMarkerWidget;


//单例模式  
class MyVtkViewWindow: public QVTKOpenGLNativeWidget
{
private:
    MyVtkViewWindow(QWidget* parent = nullptr);
    ~MyVtkViewWindow();

    //禁止拷贝构造函数
    MyVtkViewWindow(const MyVtkViewWindow&) = delete;
    MyVtkViewWindow& operator=(const MyVtkViewWindow&) = delete;

public:
    static MyVtkViewWindow* GetInstance(QWidget* parent = nullptr);


public:
    vtkRenderer* GetRenderer();
    void ResetRenderersCamera();

    vtkGenericOpenGLRenderWindow* GetRenderWindow()
    {
        return m_pRenderWindow;
    }

    vtkRenderWindowInteractor* GetRenderWindowInteractor()
    {
        return m_pRenderWindowInteractor;
    }

    vtkOrientationMarkerWidget* GetAxesMarkerWidget()
    {
        return m_pAxesMarkerWidget;
    }

    void AddActor(vtkActor* actor)
    {
        m_pActors.push_back(actor);
    }

    vtkGPUVolumeRayCastMapper* GetVolumeMapper()
    {
        if(m_pVolumeMapper == nullptr)
        {
            m_pVolumeMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
            m_pVolumeMapper->SetUseJittering(0);

            m_pMultiVolume = vtkSmartPointer<vtkMultiVolume>::New();
            m_pMultiVolume->SetMapper(m_pVolumeMapper);
            m_pRenderer->AddVolume(m_pMultiVolume);
        }

        return m_pVolumeMapper;
    }

    vtkMultiVolume* GetMultiVolume()
    {
        if(m_pVolumeMapper == nullptr)
        {
            m_pVolumeMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
            m_pVolumeMapper->SetUseJittering(0);

            m_pMultiVolume = vtkSmartPointer<vtkMultiVolume>::New();
            m_pMultiVolume->SetMapper(m_pVolumeMapper);
            m_pRenderer->AddVolume(m_pMultiVolume);
        }

        return m_pMultiVolume;
    }

    enum EViewType
    {
        E_VIEW_TYPE_VERTEX,
        E_VIEW_TYPE_EDGE,
        E_VIEW_TYPE_FACE,
    };

    void SetViewType(EViewType type);


private:
    vtkSmartPointer<vtkRenderer> m_pRenderer = nullptr;
    vtkSmartPointer<vtkCamera> m_camera = nullptr;
    vtkSmartPointer<vtkGenericOpenGLRenderWindow> m_pRenderWindow = nullptr;
    vtkSmartPointer<vtkRenderWindowInteractor> m_pRenderWindowInteractor = nullptr;
    vtkSmartPointer<vtkOrientationMarkerWidget> m_pAxesMarkerWidget = nullptr;
    vtkSmartPointer<MyVtkOrientationMarkerWidget> m_pMyVtkOrientationMarkerWidget = nullptr;


    std::vector<vtkActor*> m_pActors;
    std::vector<vtkRenderer*> m_pRenderers;
    vtkSmartPointer<vtkMultiVolume> m_pMultiVolume = nullptr;//多体渲染容器
    vtkSmartPointer<vtkGPUVolumeRayCastMapper> m_pVolumeMapper = nullptr;
};


